# Ported to CMake by StarBrilliant <m13253@hotmail.com>
# https://github.com/m13253/libsndfile-cmake

cmake_minimum_required(VERSION 3.0)
project(libsndfile)

add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)

#option(USE_STATIC_LIBSNDFILE "If set to ON, build shared library, else build static library" OFF)
set(USE_STATIC_LIBSNDFILE ON)

set(SNDFILE_SRC_SOURCES
    src/aiff.c src/alaw.c src/au.c src/audio_detect.c src/avr.c src/broadcast.c src/caf.c src/chanmap.c src/chunk.c src/command.c src/common.c src/dither.c src/double64.c src/dwd.c src/dwvw.c src/file_io.c src/flac.c src/float32.c src/g72x.c src/gsm610.c src/htk.c src/id3.c src/ima_adpcm.c src/ima_oki_adpcm.c src/interleave.c src/ircam.c src/macbinary3.c src/macos.c src/mat4.c src/mat5.c src/mpc2k.c src/ms_adpcm.c src/nist.c src/ogg.c src/ogg_pcm.c src/ogg_speex.c src/ogg_vorbis.c src/paf.c src/pcm.c src/pvf.c src/raw.c src/rf64.c src/rx2.c src/sd2.c src/sds.c src/sndfile.c src/strings.c src/svx.c src/txw.c src/ulaw.c src/voc.c src/vox_adpcm.c src/w64.c src/wav.c src/wav_w64.c src/windows.c src/wve.c src/xi.c src/G72x/g721.c src/G72x/g723_16.c src/G72x/g723_24.c src/G72x/g723_40.c src/G72x/g72x.c src/GSM610/add.c src/GSM610/code.c src/GSM610/decode.c src/GSM610/gsm_create.c src/GSM610/gsm_decode.c src/GSM610/gsm_destroy.c src/GSM610/gsm_encode.c src/GSM610/gsm_option.c src/GSM610/long_term.c src/GSM610/lpc.c src/GSM610/preprocess.c src/GSM610/rpe.c src/GSM610/short_term.c src/GSM610/table.c
)
if(USE_STATIC_LIBSNDFILE)
    add_library(sndfile STATIC ${SNDFILE_SRC_SOURCES})
else()
    add_library(sndfile SHARED ${SNDFILE_SRC_SOURCES})
endif()

set_target_properties(sndfile PROPERTIES POSITION_INDEPENDENT_CODE ON)

if(NOT MSVC)
    target_link_libraries(sndfile PUBLIC m)  # Math library
endif()

if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")  # Test subproject
    install(TARGETS sndfile
        RUNTIME DESTINATION "bin"
        LIBRARY DESTINATION "lib"
        ARCHIVE DESTINATION "lib"
    )
    install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/"
        DESTINATION "include"
    )
endif()

# Configurations
include(CheckFunctionExists)
include(CheckIncludeFiles)
include(CheckLibraryExists)
include(CheckSymbolExists)
include(CheckTypeSize)
include(TestBigEndian)
check_library_exists("m" "sin" "" SNDFILE_CONF_HAVE_LIBM)
if(SNDFILE_CONF_HAVE_LIBM)
    set(CMAKE_REQUIRED_LIBRARIES "m")
endif()
set(SNDFILE_CONF_TYPEOF_SF_COUNT_T "int64_t")
set(SNDFILE_CONF_SF_COUNT_MAX "INT64_MAX")
if(CMAKE_COMPILER_IS_GNUCC)
    set(SNDFILE_CONF_COMPILER_IS_GCC 1)
else()
    set(SNDFILE_CONF_COMPILER_IS_GCC 0)
endif()
set(SNDFILE_CONF_CPU_CLIPS_NEGATIVE 0)
set(SNDFILE_CONF_CPU_CLIPS_POSITIVE 0)
test_big_endian(SNDFILE_CONF_CPU_IS_BIG_ENDIAN)
math(EXPR SNDFILE_CONF_CPU_IS_LITTLE_ENDIAN "1-${SNDFILE_CONF_CPU_IS_BIG_ENDIAN}")
set(SNDFILE_CONF_ENABLE_EXPERIMENTAL_CODE 0)
check_include_files("alsa/asoundlib.h" SNDFILE_CONF_HAVE_ALSA_ASOUNDLIB_H)
check_include_files("byteswap.h" SNDFILE_CONF_HAVE_BYTESWAP_H)
check_function_exists("calloc" SNDFILE_CONF_HAVE_CALLOC)
check_function_exists("ceil" SNDFILE_CONF_HAVE_CEIL)
check_symbol_exists("S_IRGRP" "sys/stat.h" SNDFILE_CONF_HAVE_DECL_S_IRGRP)
check_include_files("dlfcn.h" SNDFILE_CONF_HAVE_DLFCN_H)
check_include_files("endian.h" SNDFILE_CONF_HAVE_ENDIAN_H)
set(SNDFILE_CONF_HAVE_EXTERNAL_LIBS 0)  # STUB
set(SNDFILE_CONF_HAVE_FLEXIBLE_ARRAY 1)  # STUB
check_function_exists("floor" SNDFILE_CONF_HAVE_FLOOR)
check_function_exists("fmod" SNDFILE_CONF_HAVE_FMOD)
check_function_exists("free" SNDFILE_CONF_HAVE_FREE)
check_function_exists("fstat" SNDFILE_CONF_HAVE_FSTAT)
check_function_exists("fsync" SNDFILE_CONF_HAVE_FSYNC)
check_function_exists("ftruncate" SNDFILE_CONF_HAVE_FTRUNCATE)
check_function_exists("getpagesize" SNDFILE_CONF_HAVE_GETPAGESIZE)
check_function_exists("gettimeofday" SNDFILE_CONF_HAVE_GETTIMEOFDAY)
check_function_exists("gmtime" SNDFILE_CONF_HAVE_GMTIME)
check_function_exists("gmtime_r" SNDFILE_CONF_HAVE_GMTIME_R)
check_include_files("inttypes.h" SNDFILE_CONF_HAVE_INTTYPES_H)
check_include_files("locale.h" SNDFILE_CONF_HAVE_LOCALE_H)
check_function_exists("localtime" SNDFILE_CONF_HAVE_LOCALTIME)
check_function_exists("localtime_r" SNDFILE_CONF_HAVE_LOCALTIME_R)
check_function_exists("lrint" SNDFILE_CONF_HAVE_LRINT)
check_function_exists("lrintf" SNDFILE_CONF_HAVE_LRINTF)
check_function_exists("lseek" SNDFILE_CONF_HAVE_LSEEK)
check_function_exists("malloc" SNDFILE_CONF_HAVE_MALLOC)
check_include_files("memory.h" SNDFILE_CONF_HAVE_MEMORY_H)
check_function_exists("mmap" SNDFILE_CONF_HAVE_MMAP)
check_function_exists("open" SNDFILE_CONF_HAVE_OPEN)
check_function_exists("pipe" SNDFILE_CONF_HAVE_PIPE)
check_function_exists("pread" SNDFILE_CONF_HAVE_PREAD)
check_function_exists("pwrite" SNDFILE_CONF_HAVE_PWRITE)
check_function_exists("read" SNDFILE_CONF_HAVE_READ)
check_function_exists("realloc" SNDFILE_CONF_HAVE_REALLOC)
check_function_exists("setlocale" SNDFILE_CONF_HAVE_SETLOCALE)
check_include_files("sndio.h" SNDFILE_CONF_HAVE_SNDIO_H)
check_function_exists("snprintf" SNDFILE_CONF_HAVE_SNPRINTF)
set(SNDFILE_CONF_HAVE_SQLITE3 0)  # STUB
check_type_size("ssize_t" SNDFILE_CONF_SIZEOF_SSIZE_T)
if(SNDFILE_CONF_SIZEOF_SSIZE_T)
    set(SNDFILE_CONF_HAVE_SSIZE_T 1)
else()
    set(SNDFILE_CONF_HAVE_SSIZE_T 0)
endif()
check_include_files("stdint.h" SNDFILE_CONF_HAVE_STDINT_H)
check_include_files("stdlib.h" SNDFILE_CONF_HAVE_STDLIB_H)
check_include_files("strings.h" SNDFILE_CONF_HAVE_STRINGS_H)
check_include_files("string.h" SNDFILE_CONF_HAVE_STRING_H)
check_include_files("sys/stat.h" SNDFILE_CONF_HAVE_SYS_STAT_H)
check_include_files("sys/time.h" SNDFILE_CONF_HAVE_SYS_TIME_H)
check_include_files("sys/types.h" SNDFILE_CONF_HAVE_SYS_TYPES_H)
check_include_files("sys/wait.h" SNDFILE_CONF_HAVE_SYS_WAIT_H)
check_include_files("unistd.h" SNDFILE_CONF_HAVE_UNISTD_H)
check_function_exists("vsnprintf" SNDFILE_CONF_HAVE_VSNPRINTF)
check_function_exists("waitpid" SNDFILE_CONF_HAVE_WAITPID)
check_function_exists("write" SNDFILE_CONF_HAVE_WRITE)
set(SNDFILE_CONF_NO_MINUS_C_MINUS_O 0)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
    set(SNDFILE_CONF_OS_IS_MACOSX 1)
else()
    set(SNDFILE_CONF_OS_IS_MACOSX 0)
endif()
if(WIN32)
    set(SNDFILE_CONF_OS_IS_WIN32 1)
else()
    set(SNDFILE_CONF_OS_IS_WIN32 0)
endif()
check_type_size("double" SNDFILE_CONF_SIZEOF_DOUBLE)
check_type_size("float" SNDFILE_CONF_SIZEOF_FLOAT)
check_type_size("int" SNDFILE_CONF_SIZEOF_INT)
check_type_size("int64_t" SNDFILE_CONF_SIZEOF_INT64_T)
set(SNDFILE_CONF_SIZEOF_LOFF_T 8)
check_type_size("long" SNDFILE_CONF_SIZEOF_LONG)
check_type_size("long long" SNDFILE_CONF_SIZEOF_LONG_LONG)
set(SNDFILE_CONF_SIZEOF_OFF64_T 8)
check_type_size("off_t" SNDFILE_CONF_SIZEOF_OFF_T)
set(SNDFILE_CONF_SIZEOF_SF_COUNT_T 8)
check_type_size("short" SNDFILE_CONF_SIZEOF_SHORT)
check_type_size("size_t" SNDFILE_CONF_SIZEOF_SIZE_T)
check_type_size("void *" SNDFILE_CONF_SIZEOF_VOIDP)
set(CMAKE_EXTRA_INCLUDE_FILES "wchar.h")
check_type_size("wchar_t" SNDFILE_CONF_SIZEOF_WCHAR_T)
set(CMAKE_EXTRA_INCLUDE_FILES)
set(SNDFILE_CONF_STDC_HEADERS 1)
if(WIN32)
    set(SNDFILE_CONF_USE_WINDOWS_API 1)
else()
    set(SNDFILE_CONF_USE_WINDOWS_API 0)
endif()
if(WIN32 AND NOT USE_STATIC_LIBSNDFILE)
    set(SNDFILE_CONF_WIN32_TARGET_DLL 1)
else()
    set(SNDFILE_CONF_WIN32_TARGET_DLL 0)
endif()
set(SNDFILE_CONF_WORDS_BIGENDIAN "${SNDFILE_CONF_CPU_IS_BIG_ENDIAN}")

set(CMAKE_REQUIRED_LIBRARIES)

configure_file("src/config.h.in" "src/config.h")
configure_file("src/sndfile.h.in" "include/sndfile.h")
configure_file("src/sndfile.hh" "include/sndfile.hh")
target_include_directories(sndfile PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/src")
target_include_directories(sndfile PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/include")

if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
    target_include_directories(sndfile PRIVATE "/Developer/Headers/FlatCarbon")
    find_library(SNDFILE_FRAMEWORK_COREAUDIO "CoreAudio")
    target_link_libraries(sndfile PRIVATE ${SNDFILE_FRAMEWORK_COREAUDIO})
endif()
if(WIN32)
    target_link_libraries(sndfile PRIVATE "winmm")
endif()
if(SNDFILE_CONF_HAVE_LIBM)
    target_link_libraries(sndfile PUBLIC "m")
endif()
